package org.diysearch.dao.impls;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.diysearch.dao.interfaces.TagDao;
import org.diysearch.interfaces.Taggable;
import org.diysearch.models.MyTag;
import org.diysearch.models.ObjectTag;
import org.diysearch.models.Tag;
import org.diysearch.tools.BaseTool;
import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport;

public class TagDaoImpl extends SqlMapClientDaoSupport implements TagDao {
	private static final Log LOG = LogFactory.getLog(TagDaoImpl.class);
	@Override
	public int delete(int uid, String tag) throws SQLException {
		Tag _t = new Tag();
		_t.setName(tag);
		Tag t = (Tag) getSqlMapClientTemplate().queryForObject("findTabByName",_t);
		MyTag mt = new MyTag();
		mt.setUid(uid);
		mt.setTid(t.getId());
		int dtag = getSqlMapClientTemplate().delete("delete-my-tag",mt);
		return dtag;
	}

	@Override
	public List<Tag> findByItemAndOid(int item, int oid) throws SQLException {
		ObjectTag ot = new ObjectTag();
		ot.setItem(item);
		ot.setOid(oid);
		return getSqlMapClientTemplate().queryForList("findByItemAndOid",ot);
	}

	@Override
	public List<Taggable> findItemsByOid(int oid, String tag) throws SQLException {
		ObjectTag ot = new ObjectTag();
		ot.setOid(oid);
		ot.setTag(tag);
		
		List<ObjectTag> tags = getSqlMapClientTemplate().queryForList("findByObject",ot);
		List<Taggable> results = new ArrayList<Taggable>();
		for (ObjectTag _ot : tags) {
			try {
				Taggable t = (Taggable) Class.forName(_ot.getModel()).newInstance();
				t.setItemId(_ot.getItem());
				results.add(t);
			} catch (Exception ex) {
				throw new SQLException ("yeehaw! class was not found: " + _ot.getModel());
			}
		}
		return results;
	}

	@Override
	public int save(Tag tag, MyTag myTag, ObjectTag objectTag) throws SQLException {
		Tag _t = (Tag) getSqlMapClientTemplate().queryForObject("findTabByName",tag);
		String model = BaseTool.CONFIG_BEAN.getTaggableModelsMap().get(objectTag.getOid());
		LOG.debug("Model being used for this taggable item: " + model);
		
		objectTag.setModel(model);
		
		int code = 0;
		if (_t == null) {
			// new tag, lets do the insert
			Tag _nt = (Tag) getSqlMapClientTemplate().insert("insert-tag",tag);
			objectTag.setTid(_nt.getId());
			myTag.setTid(_nt.getId());
			ObjectTag _ot = (ObjectTag) getSqlMapClientTemplate().insert("insert-object-tag",objectTag);
			MyTag _mt = (MyTag) getSqlMapClientTemplate().insert("insert-my-tag",myTag);
			code = 1;
		} else {
			// tag exists, see if it exists for this item and object
			objectTag.setTid(_t.getId());
			myTag.setTid(_t.getId());
			ObjectTag _ot = (ObjectTag) getSqlMapClientTemplate().queryForObject("findObjectTagsByItem",objectTag);
			if (_ot == null) {
				// this tag doesn't exist for this object and item
				ObjectTag _not = (ObjectTag) getSqlMapClientTemplate().insert("insert-object-tag",objectTag);
				code = 2;
			} else {
				// this tag DOES exist for this object and item, so lets increment the tag count
				MyTag _mt = (MyTag) getSqlMapClientTemplate().queryForObject("findMyTagByTidUid",myTag);
				if (_mt != null) {
					int tc = getSqlMapClientTemplate().update("increment-tag-count",_ot);
					code = 3;
				} else {
					MyTag _nmt = (MyTag) getSqlMapClientTemplate().insert("insert-my-tag",myTag);
					code = 4;
				}
			}
		}
		return code;
	}

	@Override
	public List<Tag> findTagsByUser(int uid) throws SQLException {
		MyTag mt = new MyTag();
		mt.setUid(uid);
		return getSqlMapClientTemplate().queryForList("findMyTags",mt);
	}

}
